#include "LogMessage.hpp"
#include "Protocol.hpp"
#include "Sock.hpp"

#include <memory>

void Usage(const char* args)
{
    std::cout << "Usage:\n" << args << "IP port" << std::endl;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    // 找服务端IP和Port
    uint16_t serverPort = atoi(argv[2]);
    std::string serverIp = argv[1];

    // 创建套接字
    std::unique_ptr<Sock> sock(new Sock);
    int sockfd = sock->Socket();

    // 连接服务器
    if(!sock->Connect(sockfd, serverIp, serverPort))
    {
        LogMessage(FATAL, _F, _L, "client connect fail");
        exit(2);
    }


    bool quit = false;
    while(!quit)
    {
        // 1. 获取需求
        Request req;
        std::cout << "Please Enter # ";
        std::cin >> req._x >> req._op >> req._y;

        // Request对象序列化
        std::string reqString = req.SerializeRequest();

        // Encode
        reqString = Encode(reqString);

        // 发送请求（发送序列化的字符串）
        Send(sockfd, reqString);

        // 专门接收报文的字符串
        std::string buff;
        while(1)
        {
            // 接收服务端的响应
            int ret = Recv(sockfd, buff);
            if(!ret)
            {
                quit = true;
                break;
            }

            std::string package = Decode(buff);
            if(package.empty()) continue;//如果获得空串，说明报文不完整，上去重新读取再Decode

            // 将服务端的字符串反序列化到Response对象中
            Response res;
            res.DeserializeResponse(package);

            std::string err;
            switch (res._code)
            {
            case 1:
                err = "除0错误";
                break;
            case 2:
                err = "模0错误";
                break;
            case 3:
                err = "非法操作";
                break;
            default:
                std::cout << req._x << req._op << req._y << " = " << res._result << " [success]" << std::endl;
                break;
            }
            if(!err.empty()) std::cerr << err << std::endl;

            // 一定要记着break，没有写这个搞得我我调试了一个多小时才发现的问题😅
            break;
        }
    }


    close(sockfd);

    return 0;
}